package com.android.antelopeapp.network;

import ch.boye.httpclientandroidlib.*;
import ch.boye.httpclientandroidlib.client.methods.CloseableHttpResponse;
import ch.boye.httpclientandroidlib.client.methods.HttpPost;
import ch.boye.httpclientandroidlib.entity.ContentType;
import ch.boye.httpclientandroidlib.entity.mime.MultipartEntityBuilder;
import ch.boye.httpclientandroidlib.entity.mime.content.FileBody;
import ch.boye.httpclientandroidlib.entity.mime.content.StringBody;
import ch.boye.httpclientandroidlib.impl.client.CloseableHttpClient;
import ch.boye.httpclientandroidlib.impl.client.HttpClients;
import ch.boye.httpclientandroidlib.util.EntityUtils;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;


/**
 *
 * 上传工具类
 * @author phk
 * 采用httpclient的方式上传文件
 * 支持上传文件和参数
 */
public class UploadUtil {
    private static UploadUtil uploadUtil;
    private UploadUtil() {}

    /**
     * 单例模式获取上传工具类
     * @return
     */
    public static UploadUtil getInstance() {
        if (null == uploadUtil) {
            uploadUtil = new UploadUtil();
        }
        return uploadUtil;
    }

    private static final String TAG = UploadUtil.class.getName();
    private int readTimeOut = 10 * 1000; // 读取超时
    private int connectTimeout = 10 * 1000; // 超时时间
    private int respCode ;//response的code
    private String respReson;
    /***
     * 请求使用多长时间
     */
    private static int requestTime = 0;

    private static final String CHARSET = "utf-8"; // 设置编码

    /**上传出现异常*/
    public static final int UPLOAD_EXCEPTION = -1;

    /***
     * 上传成功
     */
    public static final int UPLOAD_SUCCESS_CODE = 200;
    /**
     * 文件不存在
     */
    public static final int UPLOAD_FILE_NOT_EXISTS_CODE = 1;
    /**
     * 服务器出错
     */
    public static final int UPLOAD_SERVER_ERROR_CODE = 2;

    /**
     * android上传文件到服务器
     *
     * @param RequestURL
     *            请求的URL
     */
    public void uploadFile(final List<FileBean> files, final String RequestURL,final Map<String, String> param) {
        try {
            for(FileBean f: files){
                f.bindFile();
                if(!f.file.exists()){
                    notifyUploadDone(UPLOAD_FILE_NOT_EXISTS_CODE, "文件" + f.file.getName() + "不存在");
                    return ;
                }
            }
            new Thread(new Runnable() {  //开启线程上传文件
                @Override
                public void run() {
                    uploadSubmit(RequestURL,param,files);
                }
            }).start();
        } catch (FileNotFoundException e) {
            notifyUploadDone(UPLOAD_FILE_NOT_EXISTS_CODE, "文件不存在");
            e.printStackTrace();
            return;
        }
    }

    /**
     * 提交参数里有文件的数据
     *
     * @param url
     *            服务器地址
     * @param params
     *            参数
     * @return 服务器返回结果
     * @throws Exception
     */
    public void uploadSubmit(String url, Map<String, String> params,List<FileBean> fileBeans) {
        respCode = UPLOAD_EXCEPTION;
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost(url);
            HttpEntity reqEntity ;
            MultipartEntityBuilder mbuilder = MultipartEntityBuilder.create();
            mbuilder.setCharset(Charset.defaultCharset());

            for(Map.Entry<String,String> ety :params.entrySet()){
                mbuilder.addPart(ety.getKey(),new StringBody(ety.getValue(),ContentType.create("text/plain","UTF-8")));
            }
            for(FileBean fb : fileBeans) {
                mbuilder.addPart(fb.key,new FileBody(fb.file));
            }
            reqEntity = mbuilder.build();

            httppost.setEntity(reqEntity);

            this.notifyInitUpload();
            CloseableHttpResponse response = httpclient.execute(httppost);
            respCode = response.getStatusLine().getStatusCode();
            respReson = response.getStatusLine().getReasonPhrase();
            try {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    respCode = response.getStatusLine().getStatusCode();
                    respReson = baos.toString();
                    EntityUtils.consume(resEntity);
                }
            } finally {
                response.close();
            }
        }catch (IOException e){
            respReson = e.getMessage();
        }finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                respReson = "close httpclient error:"+e.getMessage();
            }
        }
        notifyUploadDone(respCode,respReson);
    }

    /**
     * 下面是一个自定义的回调函数，用到回调上传文件是否完成
     *
     * @author shimingzheng
     *
     */
    public static interface OnUploadProcessListener {
        /**
         * 上传响应
         * @param responseCode
         * @param message
         */
        void onUploadDone(int responseCode, String message);
        /**
         * 准备上传
         */
        void onInitUpload();
    }
    private OnUploadProcessListener onUploadProcessListener;

    private void notifyInitUpload(){
        if(onUploadProcessListener != null){
            onUploadProcessListener.onInitUpload();
        }
    }
    /**
     * 发送上传结果
     * @param responseCode
     * @param responseMessage
     */
    private void notifyUploadDone(int responseCode,String responseMessage)
    {
        if(onUploadProcessListener !=null) {
            onUploadProcessListener.onUploadDone(responseCode, responseMessage);
        }
    }



    public void setOnUploadProcessListener(
            OnUploadProcessListener onUploadProcessListener) {
        this.onUploadProcessListener = onUploadProcessListener;
    }

    public int getReadTimeOut() {
        return readTimeOut;
    }

    public void setReadTimeOut(int readTimeOut) {
        this.readTimeOut = readTimeOut;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }
    /**
     * 获取上传使用的时间
     * @return
     */
    public static int getRequestTime() {
        return requestTime;
    }

    /**
     * 上传所需要的文件信息
     *
     * */
    public static class FileBean{
        /**文件路径*/
        String filePath;
        /**文件key值，相当于html中input指定的name**/
        String key;
        /**文件实例 在上传之前会调用bindFile检测文件实例，如果文件不存在，则抛出异常**/
        File file;
        public FileBean(String filePath, String key) {
            this.filePath = filePath;
            this.key = key;
        }
        public void bindFile() throws FileNotFoundException{
            if(file == null){
                file = new File(filePath);
            }
        }
    }
}